package com.paydemo.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.paydemo.pay.RabbitMQ.PaymentMQProducer;
import com.paydemo.pay.config.AlipayConfig;
import com.paydemo.pay.entity.PayOrder;
import com.paydemo.pay.mapper.PayOrderMapper;
import com.paydemo.pay.service.PayOrderService;
import com.paydemo.pay.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 支付订单服务实现类
 */
@Slf4j
@Service
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements PayOrderService {

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private AlipayConfig alipayConfig;
    
    @Resource
    private PaymentMQProducer paymentMQProducer;

    /**
     * 创建支付宝扫码支付订单
     * @param amount 支付金额
     * @return 包含二维码内容的结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Map<String, Object>> createAlipayQrCodeOrder(BigDecimal amount) {
        try {
            // 创建订单
            String orderNo = generateOrderNo();
            PayOrder payOrder = new PayOrder();
            payOrder.setOrderNo(orderNo);
            payOrder.setTitle("支付宝扫码支付");
            payOrder.setAmount(amount);
            payOrder.setPayStatus(0); // 未支付
            payOrder.setPayType(1); // 支付宝支付
            save(payOrder);

            // 发送订单创建消息到MQ
            paymentMQProducer.sendOrderCreateMessage(payOrder);

            // 调用支付宝API创建预支付订单
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            request.setNotifyUrl(alipayConfig.getNotifyUrl());
            request.setReturnUrl(alipayConfig.getReturnUrl());

            // 组装请求参数
            Map<String, Object> bizContent = new HashMap<>();
            bizContent.put("out_trade_no", orderNo);
            bizContent.put("total_amount", amount.toString());
            bizContent.put("subject", "支付宝扫码支付");
            bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
            bizContent.put("timeout_express", "30m"); // 30分钟超时

            request.setBizContent(JSON.toJSONString(bizContent));

            // 调用支付宝接口
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                // 返回结果
                Map<String, Object> result = new HashMap<>();
                result.put("orderNo", orderNo);
                result.put("amount", amount);
                result.put("qrCode", response.getQrCode());
                return Result.success("创建订单成功", result);
            } else {
                log.error("创建支付宝预支付订单失败: {}", response.getBody());
                // 发送支付失败消息到MQ
                payOrder.setPayStatus(2); // 支付失败
                updateById(payOrder);
                paymentMQProducer.sendPaymentFailMessage(payOrder);
                return Result.error("创建支付宝预支付订单失败");
            }
        } catch (Exception e) {
            log.error("创建支付宝扫码支付订单异常", e);
            return Result.error("创建支付宝扫码支付订单异常");
        }
    }

    /**
     * 处理支付宝支付结果通知
     * @param request 请求对象
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String handleAlipayNotify(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来的反馈信息
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }

            log.info("支付宝支付结果通知，参数：{}", JSON.toJSONString(params));

            // 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getCharset(),
                    alipayConfig.getSignType());

            if (signVerified) {
                // 交易状态
                String tradeStatus = params.get("trade_status");
                // 商户订单号
                String outTradeNo = params.get("out_trade_no");
                // 支付宝交易号
                String tradeNo = params.get("trade_no");
                // 支付金额
                String totalAmount = params.get("total_amount");

                // 查询订单
                PayOrder payOrder = getByOrderNo(outTradeNo);
                if (payOrder == null) {
                    log.error("订单不存在, 订单号: {}", outTradeNo);
                    return "fail";
                }

                // 验证金额是否一致
                if (!payOrder.getAmount().toString().equals(totalAmount)) {
                    log.error("支付金额不一致，订单金额：{}，实际支付金额：{}", payOrder.getAmount(), totalAmount);
                    return "fail";
                }

                // 根据交易状态处理订单
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                    // 更新订单状态为支付成功
                    payOrder.setPayStatus(1); // 支付成功
                    payOrder.setTradeNo(tradeNo);
                    payOrder.setCallbackContent(JSON.toJSONString(params));
                    payOrder.setCallbackTime(LocalDateTime.now());
                    updateById(payOrder);
                    
                    // 发送支付成功消息到MQ
                    paymentMQProducer.sendPaymentSuccessMessage(payOrder);
                    
                    return "success";
                } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                    // 订单关闭
                    payOrder.setPayStatus(2); // 支付失败
                    payOrder.setTradeNo(tradeNo);
                    payOrder.setCallbackContent(JSON.toJSONString(params));
                    payOrder.setCallbackTime(LocalDateTime.now());
                    updateById(payOrder);
                    
                    // 发送支付失败消息到MQ
                    paymentMQProducer.sendPaymentFailMessage(payOrder);
                    
                    return "success";
                }
            } else {
                log.error("支付宝通知签名验证失败");
                return "fail";
            }
        } catch (Exception e) {
            log.error("处理支付宝回调异常", e);
        }
        return "fail";
    }

    /**
     * 处理支付宝同步返回
     * @param request 请求对象
     * @return 处理结果
     */
    @Override
    public Result<Map<String, Object>> handleAlipayReturn(HttpServletRequest request) {
        try {
            // 获取支付宝GET过来的反馈信息
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }

            log.info("支付宝页面跳转同步通知, 参数: {}", JSON.toJSONString(params));

            // 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getCharset(),
                    alipayConfig.getSignType());

            if (signVerified) {
                // 商户订单号
                String outTradeNo = params.get("out_trade_no");
                // 支付宝交易号
                String tradeNo = params.get("trade_no");
                // 查询订单信息
                PayOrder payOrder = getByOrderNo(outTradeNo);
                if (payOrder != null) {
                    Map<String, Object> result = new HashMap<>();
                    result.put("orderNo", outTradeNo);
                    result.put("tradeNo", tradeNo);
                    result.put("amount", payOrder.getAmount());
                    result.put("payStatus", payOrder.getPayStatus());
                    return Result.success("支付成功", result);
                } else {
                    return Result.error("订单不存在");
                }
            } else {
                return Result.error("验签失败");
            }
        } catch (AlipayApiException e) {
            log.error("处理支付宝同步通知异常", e);
            return Result.error("处理支付宝同步通知异常");
        }
    }
    
    /**
     * 检查订单支付超时
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkPaymentTimeout() {
        // 查询创建时间超过30分钟且状态为未支付的订单
        LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(30);
        LambdaQueryWrapper<PayOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayOrder::getPayStatus, 0)
                .lt(PayOrder::getCreateTime, timeoutTime);
        
        // 批量处理超时订单
        List<PayOrder> timeoutOrders = list(wrapper);
        if (timeoutOrders != null && !timeoutOrders.isEmpty()) {
            for (PayOrder payOrder : timeoutOrders) {
                // 更新订单状态为超时
                payOrder.setPayStatus(3); // 支付超时
                updateById(payOrder);
                
                // 发送支付超时消息到MQ
                paymentMQProducer.sendPaymentTimeoutMessage(payOrder);
                
                log.info("订单支付超时，已关闭，订单号：{}", payOrder.getOrderNo());
            }
        }
    }

    /**
     * 根据订单号获取订单
     * @param orderNo 订单号
     * @return 订单对象
     */
    @Override
    public PayOrder getByOrderNo(String orderNo) {
        LambdaQueryWrapper<PayOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayOrder::getOrderNo, orderNo);
        return getOne(wrapper);
    }

    /**
     * 生成唯一订单号
     * @return 订单号
     */
    private String generateOrderNo() {
        return "PAY" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now())
                + UUID.randomUUID().toString().substring(0, 4);
    }
} 